/**
 * @file ring_buf.h
 * @author chushang (email:chushangcs@163.com)
 * @brief 循环缓冲区
 * @version 0.1
 * @date 2025-05-01
 *
 * @copyright Copyright (c) 2025
 *
 */

#include "stdint.h"

/**
 * @brief 循环缓冲区结构体
 *
 */
typedef struct
{
    uint8_t buf_size;              // 缓冲区大小
    void   *buf;                   // 缓冲区
    uint8_t data_size;             // 有效数据的大小
    uint8_t read_index;            // 消费者索引,指向当前待读取数据的空间
    uint8_t write_index;           // 生产者索引,指向下一个待添加数据的空间
    uint8_t buf_dymanic_allocated; // buf是否属于动态分配. 1: 属于; 0: 不属于
} RingBuf;

/**
 * @brief 初始化循环缓冲区
 *
 * @param buf [in] 指向缓冲区的指针
 * @param buf_size [in] 缓冲区大小
 *
 * @return 动态分配的RingBuf指针
 * @retval NULL 分配失败; 其他: 分配成功
 */
RingBuf *RingBuf_Init(void *buf, uint8_t buf_size);

/**
 * @brief 获取缓冲区中有效数据的长度
 *
 * @param rb [in] 指向缓冲区的指针
 * @return 缓冲区中有效数据的长度
 */
uint8_t RingBuf_GetDataLength(RingBuf *rb);

/**
 * @brief 获取缓冲区中剩余空间的长度
 *
 * @param rb [in] 指向缓冲区的指针
 * @return 缓冲区中剩余空间的长度
 */
uint8_t RingBuf_GetRemainLength(RingBuf *rb);

/**
 * @brief 向缓冲区中写入数据
 *
 * @param rb [out] 缓冲区
 * @param data [in] 待写入的数据指针
 * @param length [in] 写入的长度
 * @return 写入的长度
 * @retval 0: 空间不足,写入失败; 非0: 写入成功
 */
uint8_t RingBuf_Write(RingBuf *rb, void *data, uint8_t length);

/**
 * @brief 向rb的缓冲区写入一字节数据
 *
 * @param rb   [out] 待被写入数据的缓冲区指针
 * @param data [in]  待写入的数据
 * @return 写入成功或失败：1成功，0失败
 */
uint8_t RingBuf_WriteOne(RingBuf *rb, uint8_t data);

/**
 * @brief 从rb缓冲区读取定长length数据到data中
 *
 * @param rb [in] 缓冲区指针
 * @param data [out] 待写入的指针
 * @param length [in] 数据长度
 * @return 读取的数据长度
 * @retval 0: 读取失败,数据长度不足; 非0: 读取成功
 */
uint8_t RingBuf_Read(RingBuf *rb, void *data, uint8_t length);

/**
 * @brief 从缓冲区读取一字节数据
 *
 * @param rb   [in]  指向缓冲区的指针
 * @param data [out] 存放数据的指针
 * @return 0：缓冲区无数据；1：读取成功，返回数据
 */
uint8_t RingBuf_ReadOne(RingBuf *rb, uint8_t *data);
